//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2003 Intrinsyc Europe Ltd.
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004 Siemens AG
//
// Version: 1.1.2.5
// Date:    11. Jan. 2006
//////////////////////////////////////////////////////////////////////////////


#pragma once

// Used by CResponse
#define ALLOC_SIZE                      1024

// Specific value for Siemens Modules: maximum numbers of lines to be handled
#define MAX_NUMBERCALLS                 10

#if !defined(RIL_NOTIFY_LOCATIONUPDATE)
#ifndef RIL_NO_CREG_LOCATION_UPDATES
#define RIL_NO_CREG_LOCATION_UPDATES
#endif
#endif

//
// Error mapping structure used for binary search
//
struct ERRORMAP {
    HRESULT hrError;
    DWORD dwCode;
};

//
// USSD error causes
//
struct USSDERRORCAUSE
{
    DWORD  dwCEER_LocID;
    DWORD  dwCEER_reason;
    DWORD  dwCEER_ssRel;
    UINT   uiErrorText;
};

#ifdef RIL_INDICATE_SS_INFORMATION
//
// USSD error causes
//
struct SSINDICATION
{
    DWORD  dwSS_ind;
    UINT   uiErrorText;
};
#endif

inline void *AllocBlob(UINT bytes)
{
    return (void *)LocalAlloc(LMEM_MOVEABLE,bytes);
}

inline void *FreeBlob(void *pblob)
{
    return (void *)LocalFree(pblob);
}

inline void *ReallocBlob(void *pblob, UINT bytes)
{
    if (!pblob)
    {
        return (void *)LocalAlloc(LMEM_MOVEABLE,bytes);
    }

    return (void *)LocalReAlloc(pblob,bytes,LMEM_MOVEABLE);
}

class CRilHandle;
//
// AT command response
//
class CResponse : public CBuffer
{
public:
            CResponse(COM_PORT_TYPE PortType, CRilHandle *pRilHandle);
            ~CResponse();
            CResponse(const CResponse &Rsp);

    BOOL    AppendString(const LPCSTR szString, const UINT cbString, LPCSTR& rszRemainder, UINT& rcbRemainder);
    BOOL    SetBlob(const void* const pBlob, const UINT cbBlob);
    BOOL    MakeError(const HRESULT hr);
    void    DeleteBlob()                                { FreeBlob(m_pBlob); m_pBlob = NULL; m_cbBlob = 0; };
    void    MakeOK()                                    { m_dwCode = RIL_RESULT_OK; m_fUnsolicited = FALSE; };
    BOOL    ParseOKOrErrorData(CCommand*&rpCmd, BOOL fCmdOk);
    HRESULT GetError() const;
    void    GetBlob(void*& rpBlob, UINT& rcbBlob) const { rpBlob = m_pBlob; rcbBlob = m_cbBlob; };
    DWORD   GetNotifyCode() const                       { return m_dwCode; };
    BOOL    FUnsolicited() const                        { return !!m_fUnsolicited; };
    BOOL    FUnrecognized() const                       { return !!m_fUnrecognized; };
    void    ConnectToOK()   { TBD_ASSERT(RIL_NOTIFY_CONNECT == m_dwCode);   m_dwCode = RIL_RESULT_OK; m_fUnsolicited = FALSE; };
    void    NoCarrierToOK() { TBD_ASSERT(RIL_RESULT_NOCARRIER == m_dwCode); m_dwCode = RIL_RESULT_OK; m_fUnsolicited = FALSE; };
    void    SetCallAborted() { m_dwCode = RIL_RESULT_CALLABORTED; m_fUnsolicited = FALSE; };
    BOOL    OKToError(HRESULT hr);
    void    SetPotentialBogusResponseFlag() { m_fPotentialBogusResponse = TRUE; }

private:
    BOOL    SearchV1Response(LPCSTR& szPointer, UINT *uiRetCode);
    BOOL    Parse(UINT& rcbNewLength);
    BOOL    ParseOKOrError(const BOOL fOK, UINT& rcbNewLength);
    BOOL    ParseNotification(UINT& rcbNewLength);
    BOOL    ParseV25Response(UINT nResponseCode);
    BOOL    ParseExtError(LPCSTR& rszPointer, const ERRORMAP* const rgemMap, const UINT nMapEntries, UINT &nCode, BOOL fSigned);
    BOOL    ParseExtRing(LPCSTR& rszPointer, DWORD *pdwCallType);
    BOOL    ParseServiceInfo(LPCSTR& rszPointer);
    BOOL    ParseRemotePartyInfo(LPCSTR& rszPointer, BOOL fCLIP);
    BOOL    ParseCallWaitingInfo(LPCSTR& rszPointer);
#ifdef SIEMENS_MAGNETO
    BOOL    ParseUnsolicitedSSInfo(LPCSTR& szPointer);
    BOOL    ParseIntermediateSSInfo(LPCSTR& szPointer);
#endif
    BOOL    ParseCallMeter(LPCSTR& rszPointer);
    BOOL    ParseIndicatorEventValue(LPCSTR& rszPointer);
#ifdef RIL_ENABLE_ALS
    BOOL    ParseALSStatusStatus(LPCSTR& rszPointer);
#endif
    BOOL    ParseRegistrationStatus(LPCSTR& rszPointer, DWORD const dwNotifyCode);
    BOOL    ParseSIMCardStatus(LPCSTR& rszPointer);
    BOOL    ParseTemperatureWarning(LPCSTR& rszPointer, INT &iCause);
    BOOL    ParseUSSDInfo(LPCSTR& rszPointer, BOOL &fExpectNothing);
    BOOL    ParseMessage(LPCSTR& rszPointer, DWORD const dwNotifyCode);
    BOOL    ParseMessageInSim(LPCSTR& rszPointer, DWORD const dwNotifyCode, BOOL fNoNotification = FALSE);
    BOOL    ParseSIMToolkitCmdOrRsp(LPCSTR& rszPointer, const DWORD dwNotifyCode);
    BOOL    ParseSIMToolkitCallSetup(LPCSTR& rszPointer);
    void    ParseJunk(UINT nCRLFs, LPCSTR& rszPointer);
    BOOL    ParseCallListNotification(LPCSTR& rszPointer);
    BOOL    ParseRadioSysstart(LPCSTR& rszPointer);
    BOOL    ParseRadioShutdown(LPCSTR& rszPointer);
    BOOL    ParseTemperatureShutdown(LPCSTR& rszPointer);
    BOOL    IsProbablyNotUCS2(LPCSTR szDataString);
    void     HandleUSSDError();

    DWORD          m_dwCode;
    void*          m_pBlob;
    UINT           m_cbBlob;
    DWORD          m_fUnsolicited : 1;
    DWORD          m_fUnrecognized : 1;
    DWORD          m_fPotentialBogusResponse : 1;
    COM_PORT_TYPE  m_PortType;
    RILCALLINFO    m_CallInfo[MAX_NUMBERCALLS];
    UINT           m_iNrCallInfo;
    CRilHandle*    m_pRilHandle;
};


//
// Notification data
//
class CNotificationData
{
public:
                        CNotificationData();
                        ~CNotificationData();

    BOOL                InitFromDWORDBlob(const DWORD dwCode, const DWORD dwBlob);
    BOOL                InitFromRealBlob(const DWORD dwCode, const void* const pBlob, UINT cbBlob);
    BOOL                FinishInitFromRspBlob(const CResponse& rRsp);
    BOOL                DelayInitFromRspBlob(const DWORD dwCode);

    BOOL                FDelayedInitFromRsp() const { return !!m_fDelayedInitFromRsp; };
    DWORD               GetCode() const             { TBD_ASSERT(FALSE != !!m_fInited); return m_dwCode; };
    const void* const   GetBlob() const             { TBD_ASSERT(FALSE != !!m_fInited); return m_pBlob; };
    UINT                GetSize() const             { TBD_ASSERT(FALSE != !!m_fInited); return m_cbBlob; };

private:
    DWORD       m_dwCode;
    void*       m_pBlob;
    UINT        m_cbBlob;
    DWORD       m_fInited : 1;
    DWORD       m_fDelayedInitFromRsp : 1;
};

#ifdef RIL_ENABLE_ALS
extern     UINT           g_dwALSLine;
#endif

